﻿//https://www.cnblogs.com/atomy/p/12345743.html
using System.Collections;

namespace InterpreterPattern;
public static class Program
    {
        /// <summary>
        /// 环境上下文
        /// </summary>
        public sealed class Context
        {
            public string Statement { get; set; }

            public int Data { get; set; }

            public Context(string statement)
            {
                Statement = statement;
            }
        }

        /// <summary>
        /// 抽象表达式
        /// </summary>
        public abstract class Expression
        {
            protected readonly Dictionary<string, int> Table = new(9);

            protected Expression()
            {
                Table.Add("一", 1);
                Table.Add("二", 2);
                Table.Add("三", 3);
                Table.Add("四", 4);
                Table.Add("五", 5);
                Table.Add("六", 6);
                Table.Add("七", 7);
                Table.Add("八", 8);
                Table.Add("九", 9);
            }

            public virtual void Interpreter(Context context)
            {
                if (context.Statement.Length == 0)
                {
                    return;
                }

                foreach (string key in Table.Keys)
                {
                    int value = Table[key];

                    if (context.Statement.EndsWith(key + GetPostFix()))
                    {
                        context.Data += value * Multiplier();
                        context.Statement = context.Statement.Substring(0, context.Statement.Length - GetLength());
                    }
                    if (context.Statement.EndsWith("零"))
                    {
                        context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
                    }
                }
            }

            public abstract string GetPostFix();

            public abstract int Multiplier();

            //十、百、千位数使用，所以用虚方法。
            public virtual int GetLength()
            {
                return GetPostFix().Length + 1;
            }
        }

        /// <summary>
        /// 个位表达式
        /// </summary>
        public sealed class GeExpression : Expression
        {
            public override string GetPostFix()
            {
                return "";
            }

            public override int Multiplier()
            {
                return 1;
            }

            public override int GetLength()
            {
                return 1;
            }
        }

        /// <summary>
        /// 十位表达式
        /// </summary>
        public sealed class ShiExpression : Expression
        {
            public override string GetPostFix()
            {
                return "十";
            }

            public override int Multiplier()
            {
                return 10;
            }
        }

        /// <summary>
        /// 百位表达式
        /// </summary>
        public sealed class BaiExpression : Expression
        {
            public override string GetPostFix()
            {
                return "百";
            }

            public override int Multiplier()
            {
                return 100;
            }
        }

        /// <summary>
        /// 千位表达式
        /// </summary>
        public sealed class QianExpression : Expression
        {
            public override string GetPostFix()
            {
                return "千";
            }

            public override int Multiplier()
            {
                return 1000;
            }
        }

        /// <summary>
        /// 万位表达式
        /// </summary>
        public sealed class WanExpression : Expression
        {
            public override string GetPostFix()
            {
                return "万";
            }

            public override int Multiplier()
            {
                return 10000;
            }

            public override int GetLength()
            {
                return 1;
            }

            public override void Interpreter(Context context)
            {
                if (context.Statement.Length == 0)
                {
                    return;
                }

                ArrayList tree =
                [
                    new GeExpression(),
                    new ShiExpression(),
                    new BaiExpression(),
                    new QianExpression()
                ];

                foreach (string key in Table.Keys)
                {
                    if (context.Statement.EndsWith(GetPostFix()))
                    {
                        int temp = context.Data;
                        context.Data = 0;

                        context.Statement = context.Statement.Substring(0, context.Statement.Length - GetLength());

                        foreach (Expression exp in tree)
                        {
                            exp.Interpreter(context);
                        }
                        context.Data = temp + context.Data * Multiplier();
                    }
                }
            }
        }

        /// <summary>
        /// 亿位表达式
        /// </summary>
        public sealed class YiExpression : Expression
        {
            public override string GetPostFix()
            {
                return "亿";
            }

            public override int Multiplier()
            {
                return 100000000;
            }

            public override int GetLength()
            {
                return 1;
            }

            public override void Interpreter(Context context)
            {
                ArrayList tree =
                [
                    new GeExpression(),
                    new ShiExpression(),
                    new BaiExpression(),
                    new QianExpression()
                ];

                foreach (string key in Table.Keys)
                {
                    if (context.Statement.EndsWith(GetPostFix()))
                    {
                        int temp = context.Data;
                        context.Data = 0;
                        context.Statement = context.Statement.Substring(0, context.Statement.Length - GetLength());

                        foreach (Expression exp in tree)
                        {
                            exp.Interpreter(context);
                        }
                        context.Data = temp + context.Data * Multiplier();
                    }
                }
            }
        }

       public static void Main()
        {
            #region 解释器模式
            //分解：((五)亿)((七千)(三百)(零)(二)万) ((六千)(四百)(五十)(二))
            string roman = "五亿七千三百零二万六千四百五十二";

            Context context = new Context(roman);
            ArrayList tree =
            [
                new GeExpression(),
                new ShiExpression(),
                new BaiExpression(),
                new QianExpression(),
                new WanExpression(),
                new YiExpression()
            ];

            foreach (Expression exp in tree)
            {
                exp.Interpreter(context);
            }

            Console.Write(context.Data);

            Console.Read();
            #endregion
        }
    }